library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity fir_filter_n is
	generic ( N : integer := 16);
	port (
		nreset_i	: in  std_logic;
		clk_i 		: in  std_logic;
		x_i   		: in  std_logic_vector(N-1 downto 0);
		y_o   		: out std_logic_vector(N-1 downto 0)
	);
end fir_filter_n;

architecture behav of fir_filter_n is

	signal x_reg : std_logic_vector(N-1 downto 0);

begin

	process(clk_i)
	begin
		if(clk_i = '1' and clk_i'event) then
			if(nreset_i = '0') then
				x_reg <= (others => '0');
			else
				x_reg <= x_i;
			end if;
		end if;
	end process;

	y_o <= x_reg + x_i;

end behav;

architecture struc of fir_filter_n is

	component adder_n
		generic (
			N : integer := 4
		);
		port (
		   	a_i    : in  std_logic_vector(N-1 downto 0);
    		b_i    : in  std_logic_vector(N-1 downto 0);
    		cin_i  : in  std_logic;
			y_o    : out std_logic_vector(N-1 downto 0);
			cout_o : out std_logic
		);
	end component;

	component register_n
		generic (
			N : integer := 4
		);
		port (
			clk_i 	 : in  std_logic;
			nreset_i : in  std_logic;
			we_i	 : in  std_logic;
			d_i      : in  std_logic_vector(N-1 downto 0);
			q_o      : out std_logic_vector(N-1 downto 0)
		);
	end component;

	signal x_reg : std_logic_vector(N-1 downto 0);

begin

	adder_inst : adder_n generic map (
		N => N
	) port map (
		a_i    => x_i, 
		b_i    => x_reg,
		cin_i  => '0',
		y_o    => y_o,
		cout_o => open
	);

	register_inst : register_n generic map (
		N => N
	) port map (
		clk_i 	 => clk_i, 
		nreset_i => nreset_i,
		we_i	 => '1',
		d_i      => x_i,
		q_o      => x_reg
	);

end struc;
